from functools import reduce


# 内置函数
a = abs(-2.34)
print(a)
# 用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE，如果是返回 True，否则返回 False。元素除了是 0、空、None、False 外都算 True
print("\na ------------------------")
print(all(['a', 'b', 'c', 'd']))    # 列表，元素都不为空或0       True
print(all(['a', 'b', '', 'd']))     # 列表，存在一个为空的元素     False
print(all((0, 1, 2, 3)))            # 元组，存在一个为0的元素      False
print(all(()))                      # 空元组                    True
# 用于判断给定的可迭代参数 iterable 是否全部为 False，则返回 False，如果有一个为 True，则返回 True。元素除了是 0、空、FALSE 外都算 TRUE
print(any(('a', 'b', 'c', 'd')))    # 元组tuple，元素都不为空或0   True
print(any(('a', 'b', '', 'd')))     # 元组tuple，存在一个为空的元素 True
print(any([0, '', False]))          # 列表, 元素全为0,'',false    False
print(any([]))                      # 空列表                     False


# basestring 已过期
print("\nb ------------------------")
print(isinstance("hello world", str))           # True
# print(isinstance("Hello world", basestring))  # delete in python3
print(bin(10))                      # 返回一个整数 int 或者长整数 long int 的二进制表示  0b1010
print(bytearray([1, 2, 3]))         # 返回一个新字节数组   bytearray(b'\x01\x02\x03')
print(bytearray('hello', 'utf-8'))  # 返回一个新字节数组   bytearray(b'hello')


# 检查一个对象是否是可调用的, 对于函数、方法、lambda 函式、 类以及实现了 __call__ 方法的类实例, 它都返回 True
print("\nc ------------------------")
print(callable("hello"))            # False
print(callable(a))                  # 没有实现 __call__, 返回 False
# 0-255整数作参数，返回一个对应的字符
print(chr(65), chr(0x31), chr(0x32))  # A 1 2
# 用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数
print(complex(1))                   # (1+0j)
print(complex(1, 2))                # (1+2j)
print(complex("4+5j"))              # (4+5j)


# 创建一个字典
print("\nd ------------------------")
print(dict(a='A', b='B', t='T'))                        # 传入关键字方式  {'t': 'T', 'a': 'A', 'b': 'B'}
print(dict(zip(['one', 'two', 'three'], [1, 2, 3])))    # 映射函数方式    {'three': 3, 'one': 1, 'two': 2}
print(dict([('one', 1), ('two', 2), ('three', 3)]))     # 可迭代对象方式  {'three': 3, 'one': 1, 'two': 2}
# 不带参数时，返回当前范围内的变量、方法和定义的类型列表；带参数时，返回参数的属性、方法列表
print(dir())    # 获得当前模块的属性列表 ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'reduce']
print(dir([]))  # 查看列表的方法 ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
# 把除数和余数运算结果结合起来
print(divmod(7, 2))     # (3, 1)


# 将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列，同时列出数据和数据下标，一般用在 for 循环当中
print("\ne ------------------------")
print(list(enumerate(['a', 'b', 'c'], start=2)))    # [(2, 'a'), (3, 'b'), (4, 'c')]
# 执行一个字符串表达式，并返回表达式的值
x = 7
print(eval('x + 3'))        # 10
print(eval("pow(3, 3)"))    # 27


# 用于过滤序列，过滤掉不符合条件的元素，返回由符合条件元素组成的新列表, filter，只是将满足条件y>2的数据过滤提取出来，不会进行赋值，所以x+1是没有效果的
print("\nf ------------------------")
a = [1, 2, 3, 4]
print(list(filter(lambda y: y > 2, a)))        # [3, 4]
print(list(filter(lambda y: y + 1, a)))        # [1, 2, 3, 4]
# 增强了字符串格式化的功能。基本语法是通过 {} 和 : 来代替以前的 %
print("{}{}".format("hello", "world"))         # 不设置指定位置，按默认顺序  helloworld
print("{1} {1} {0}".format("hello", "world"))  # 设置指定位置             world world hello
print("网站名：{name}, 地址 {url}".format(name="菜鸟教程", url="www.runoob.com"))    # 网站名：菜鸟教程, 地址 www.runoob.com
site = {"name": "菜鸟教程", "url": "www.runoob.com"}
print("网站名：{name}, 地址 {url}".format(**site))     # 通过字典设置参数              # 网站名：菜鸟教程, 地址 www.runoob.com
my_list = ['菜鸟教程', 'www.runoob.com']
print("网站名：{0[0]}, 地址 {0[1]}".format(my_list))   # # 通过列表索引设置参数, "0" 是必须的
print("{:.2f}".format(3.1415926))       # 3.14
# 返回一个冻结的集合，冻结后集合不能再添加或删除任何元素
print(frozenset(range(10)))             # frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})


# 以字典类型返回当前位置的全部全局变量
print("\ng ------------------------")
print(globals())  # {'reduce': <built-in function reduce>, '__cached__': None, '__file__': '/home/workspace1/workplace/python/python-learning/basic/04_function_buildin.py', '__package__': None, '__name__': '__main__', 'a': 2.34, '__doc__': None, '__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f075237dba8>}


# 查看函数或模块用途的详细说明
print(help(abs))
# 获取哈希值, 可以应用于数字、字符串和对象，不能直接应用于 list、set、dictionary
print("\nh ------------------------")
print(hash(1))          # 1
print(hash('hello'))    # 4644945189706580958

# 获取对象的内存地址
print("\ni ------------------------")
print(id(x))            # 10853824
# Python3.x 中 input() 函数接受一个标准输入数据，返回为 string 类型
# a = input("please input 123: ")
# print(a, type(a))                # 123 <class 'str'>
# a = input("please input abc: ")
# print(a, type(a))                # abc <class 'str'>

# isinstance() 函数来判断一个对象是否是一个已知的类型，类似 type(), 但是type()不会认为子类是一种父类类型，不考虑继承关系
# classinfo: int，float，bool，complex，str(字符串)，list，dict(字典)，set，tuple
print(isinstance(1, int))               # True
print(isinstance('hello', int))         # False
print(isinstance(1, (int, str, list)))  # True
# 将元组转换为列表
print(list((1, 2, 3, 'a', 'b', 'c')))   # [1, 2, 3, 'a', 'b', 'c']


# 根据提供的函数对指定序列做映射, Python 3.x 返回迭代器
print("\nm ------------------------")
b = [5, 6, 7]                            # a = [1, 2, 3, 4]
print(map(max, b))
print(list(map(lambda x: x+1, b)))       # [6, 7, 8]
print(list(map(lambda x, y: x+y, a, b))) # [6, 8, 10]
print(hex(10))
# 给定参数的内存查看对象
mv = memoryview(bytearray("hello", 'utf-8'))
print(mv[0], mv[1], mv[2], mv[-1])       # 104 101 108 111
print(mv[0:4].tobytes())                 # b'hell'


# 创建一个整数列表，一般用在 for 循环中, range(start, stop, step)
print("\nr ------------------------")
print(tuple(range(8)))                   # (0, 1, 2, 3, 4, 5, 6, 7)
print(tuple(range(-1, 8, 2)))            # (-1, 1, 3, 5, 7)
# 对参数序列中元素进行累积 reduce(function, iterable[, initializer])
print(reduce(lambda x, y:x+y, a, 1))     # 11 ((((1+1)+2) + 3) + 4)      a = [1, 2, 3, 4]
# 没有返回值，但是会对list反转
a.reverse()
print(a)                                 # [4, 3, 2, 1]
# 返回浮点数的四舍五入值
print(round(3.1415, 2))                  # 3.14
print(round(3.6789, 3))                  # 3.679


# 实现切片对象，主要用在切片操作函数里的参数传递 slice(start, stop[, step])
print("\ns ------------------------")
r = range(10)
myslice = slice(1, 8, 2)
print(list(r[myslice]))                  # [1, 3, 5, 7]
print(sorted(r, reverse=True))           # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
print(sorted(students, key=lambda s: s[2]))     # 按key 年龄排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
print(sum(r))       # 45
print(sum(r, 2))    # 47


# 将列表转换为元组
print("\nt ------------------------")
print(tuple([1, 3, 5, 'c', 'f']))        # (1, 3, 5, 'c', 'f')


# 返回对象object的属性和属性值的字典对象
print("\nv ------------------------")
x = 1
v = vars()
print(v)            # {'b': [5, 6, 7], '__file__': '/home/workspace1/workplace/python/python-learning/basic/04_function_buildin.py', '__package__': None, 'myslice': slice(1, 8, 2), '__cached__': None, '__spec__': None, 'r': range(0, 10), '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, 'v': {...}, 'mv': <memory at 0x7efcf53dfe88>, '__name__': '__main__', 'a': [4, 3, 2, 1], 'reduce': <built-in function reduce>, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7efcf6ba7ba8>, 'x': 1, 'my_list': ['菜鸟教程', 'www.runoob.com'], 'students': [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)], 'site': {'name': '菜鸟教程', 'url': 'www.runoob.com'}}
print(v['x'])       # 1


# 将可迭代的对象作为参数，将对象中对应的元素打包成一个个元组，然后返回由这些元组组成的列表
print("\nz ------------------------")
t1 = (1, 2, 3, 4)
t2 = (5, 6, 7)
for i in zip(t1, t2):
    print(i)
    # (1, 5)
    # (2, 6)
    # (3, 7)
d1 = {'sky': 'male', 'lotus': 'female'}
d2 = zip(d1.values(), d1.keys())
print(dict(d2))                             # [('male', 'sky'), ('female', 'lotus')]
# *t3可以理解为解压
t3 = zip(t1, t2)
for i in zip(*t3):
    print(i)
    # (1, 2, 3)
    # (5, 6, 7)

# 执行储存在字符串或文件中的Python语句，相比于 eval，exec可以执行更复杂的 Python 代码
exec('print("hello world")')                # hello world

exec("""
for i in range(4):
    print(i)
""")
# 0
# 1
# 2
# 3
